using System.Runtime.Serialization;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using INdT.Sparta.Physics; 

namespace INdT.Sparta.Graphics
{
    [DataContract]
    public class SpartaTexture : SpartaDrawable
    {
        public virtual Texture2D Texture { get; set; }

        [DataMember]
        public SpriteEffects SpriteEffect { get; set; }

        public override int Width
        {
            get { return Texture == null ? 0 : Texture.Width; }
        }

        public override int Height
        {
            get { return Texture == null ? 0 : Texture.Height; }
        }

        public override float X
        {
            get
            {
                if (PhysicsObject == null)
                {
                    return base.X;
                }
                else
                {
                    return Position.X;
                }
            }
            set
            {
                base.X = value;
            }
        }
        public override float Y
        {
            get
            {
                if (PhysicsObject == null)
                {
                    return base.Y;
                }
                else
                {
                    return Position.Y;
                }
            }
            set
            {
                base.Y = value;
            }
        }

        public override Vector2 Position
        {
            get
            {
                if (PhysicsObject == null)
                {
                    return base.Position;
                }
                else
                {
                    return SpartaPhysics.ConvertUnits(PhysicsObject.Position);
                }
            }
            set
            {
                if (PhysicsObject == null)
                {
                    base.Position = value;
                }
                else
                {
                    PhysicsObject.Position = value;
                }
            }
        }

        public override Vector2 Origin
        {
            get
            {
                if (PhysicsObject == null)
                {
                    return base.Origin;
                }
                else
                {
                    return new Vector2(BoundingBox.Width / 2, BoundingBox.Height / 2);
                }
            }
            set
            {
                base.Origin = value;
            }
        }

        public override float Angle
        {
            get
            {
                if (PhysicsObject == null)
                {
                    return base.Angle;
                }
                else
                {
                    return PhysicsObject.Rotation;
                }
            }
            set
            {
                if (PhysicsObject == null)
                {
                    base.Angle = value;
                }
                else
                {
                    PhysicsObject.Rotation = value;
                }
            }
        }

        [DataMember]
        public virtual string TextureAssetName { get; set; }

        [DataMember]
        public virtual Rectangle SourceRect { get; set; }

        [DataMember]
        public virtual float LayerDepth { get; set; }

        public Body PhysicsObject;

        public SpartaTexture()
            : this(string.Empty)
        {
            PhysicsObject = null;
        }

        public SpartaTexture(string imageName)
        {
            TextureAssetName = imageName;
            PhysicsObject = null;
        }

        public override void LoadContent()
        {
            if (string.IsNullOrEmpty(TextureAssetName))
            {
                return;                
            }

            Texture = SpartaGame.Instance.LoadTexture(TextureAssetName);            
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            if (Texture == null || !Visible)
            {
                return;
            }


            if (SourceRect.IsEmpty)
            {
                spriteBatch.Draw(Texture, this.Position, null, Color, Angle, Origin, Scale, SpriteEffect, LayerDepth);
            }
            else
            {
                spriteBatch.Draw(Texture, Position, SourceRect, Color, Angle, Origin, Scale, SpriteEffect, LayerDepth);
            }

            base.Draw(gameTime, spriteBatch);
        }
    }
}
